#
# Created: 2025-07-27

import numpy as np
import pandas as pd
import random
from pyecharts.charts import Sankey
from pyecharts import options as opts

# 设置随机种子
random.seed(42)
np.random.seed(42)

# -------------------------------
# 一、定义每层选项
# -------------------------------
layers = {
    "出发城市": ["A城", "B城", "C城"],
    "出游关系": ["家庭出游", "朋友同行", "情侣旅行", "独自探险", "公司团建", "同学出游", "网友相约", "亲子出行"],
    "出游方式": ["跟团游", "自由行", "自驾游", "骑行游", "深度游", "房车旅行", "高铁旅行", "邮轮游"],
    "出游天数": ["1日游", "2日游", "3日游", "4~5日游", "6~7日游", "8日及以上"],
    "游览景点": ["景点A", "景点B", "景点C", "景点D", "景点E", "景点F", "景点G", "景点H"],
    "偏好类型": ["美食体验", "自然风光", "文化遗产", "游乐园", "拍照打卡", "博物探索", "地道生活", "夜市闲逛", "手工DIY", "探险项目"],
    "满意度": ["非常满意", "满意", "一般满意", "不满意", "非常不满意"],
    "推荐意向": ["强烈推荐", "推荐", "一般推荐", "不推荐"]
}
layer_keys = list(layers.keys())

# -------------------------------
# 二、构造路径数据并保存
# -------------------------------
num_samples = 60
data = []
for _ in range(num_samples):
    row = [np.random.choice(options) for options in layers.values()]
    data.append(row)

df_paths = pd.DataFrame(data, columns=layers.keys())
df_paths.to_csv("diverse_paths.csv", index=False, encoding="utf_8_sig")  # ✅ 保存路径数据

# -------------------------------
# 三、构造边数据并保存
# -------------------------------
edges = []
for row in data:
    for i in range(len(row) - 1):
        edges.append((row[i], row[i + 1]))

df_links = pd.DataFrame(edges, columns=["source", "target"])
df_sankey = df_links.value_counts().reset_index(name="value")
df_sankey.to_csv("sankey_edges.csv", index=False, encoding="utf_8_sig")  # ✅ 保存边数据

# -------------------------------
# 四、定义颜色映射
# -------------------------------
departure_colors = {
    "A城": "#FF8A65",
    "B城": "#F06292",
    "C城": "#b1a5c9"
}
recommendation_colors = {
    "强烈推荐": "#b0d1a6",
    "推荐": "#e3716e",
    "一般推荐": "#e7a39a",
    "不推荐": "#b1a5c9"
}
layer_colors = ['#bde6f7','#80dcfb','#f1c5d8','#eda3aa','#d1e6c4','#98e0ac','#f3d8bc','#f1f1f1']

# -------------------------------
# 五、构造 nodes 和 links
# -------------------------------
nodes = []
for i, (layer_name, layer_values) in enumerate(layers.items()):
    for node in layer_values:
        if layer_name == "出发城市":
            color = departure_colors.get(node, "#BDBDBD")
        elif layer_name == "推荐意向":
            color = recommendation_colors.get(node, "#9E9E9E")
        else:
            color = layer_colors[i]
        nodes.append({
            "name": node,
            "itemStyle": {"color": color}
        })

links = []
for _, row in df_sankey.iterrows():
    links.append({
        "source": row["source"],
        "target": row["target"],
        "value": int(row["value"])
    })

# -------------------------------
# 六、绘制桑基图
# -------------------------------
html_file = "sankey_colored_saved.html"

sankey = (
    Sankey(init_opts=opts.InitOpts(width="1500px", height="800px"))
    .add(
        "",
        nodes=nodes,
        links=links,
        linestyle_opt=opts.LineStyleOpts(opacity=0.3, curve=0.5, color="source"),
        label_opts=opts.LabelOpts(position="right", font_size=14),
        node_gap=20,
        node_width=15,
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="")
    )
)
sankey.render(html_file)

# -------------------------------
# 七、插入底部标签 HTML
# -------------------------------
# 修改HTML插入部分（最终精准定位版）
layer_labels = '''
<div style="position: absolute;
            left: 40px;  /* 关键参数：向左移动40像素 */
            top: 10px;
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            width: 1100px;  /* 略小于画布宽度 */
            font-size: 16px;
            font-weight: bold;
            font-family: 'Microsoft YaHei';
            text-align: center;">
  <div style="transform: translateX(-15px)">出发城市</div>
  <div style="transform: translateX(1px)">出游关系</div>
  <div style="transform: translateX(25px)">出游方式</div>
  <div style="transform: translateX(45px)">出游天数</div>
  <div style="transform: translateX(65px)">游览景点</div>
  <div style="transform: translateX(85px)">偏好类型</div>
  <div style="transform: translateX(110px)">满意度</div>
  <div style="transform: translateX(130px)">推荐意向</div>
</div>
'''



with open(html_file, "r", encoding="utf-8") as f:
    html = f.read()

html = html.replace("</body>", layer_labels + "\n</body>")

with open(html_file, "w", encoding="utf-8") as f:
    f.write(html)

# -------------------------------
# 八、输出信息
# -------------------------------
print("✅ 桑基图已生成：sankey_colored_saved.html")
print("✅ 路径数据已保存：diverse_paths.csv")
print("✅ 边数据已保存：sankey_edges.csv")
print("✅ 图层标签已插入页面底部")
